;(function() {
	if (window.WebViewJavascriptBridge) {
            return;
	}

	var messagingIframe;
	var sendMessageQueue = [];
	var receiveMessageQueue = [];
	var messageHandlers = {};

	var CUSTOM_PROTOCOL_SCHEME = 'wvjbscheme';
	var QUEUE_HAS_MESSAGE = '__QUEUE_MESSAGE__/';

	var responseCallbacks = {};
	var uniqueId = 1;

	function _createQueueReadyIframe(doc) {
		messagingIframe = doc.createElement('iframe');
		messagingIframe.style.display = 'none';
		doc.documentElement.appendChild(messagingIframe);
	}

	function _defaultHandler(data, responseCallback) {
		alert("defaultHandler:" + data);
		responseCallback("defaultHandler : callback");
	}
	//set default messageHandler
	function init() {
		WebViewJavascriptBridge._messageHandler = _defaultHandler;
		var receivedMessages = receiveMessageQueue;
		receiveMessageQueue = null;
		for (var i = 0; i < receivedMessages.length; i++) {
			_dispatchMessageFromNative(receivedMessages[i]);
		}
	}

	function send(data, responseCallback) {
		_doSend({
			data: data
		}, responseCallback);
	}

	function registerHandler(handlerName, handler) {
		messageHandlers[handlerName] = handler;
	}

	function callHandler(handlerName, data, responseCallback) {
		_doSend({
			handlerName: handlerName,
			data: data
		}, responseCallback);
	}

	//sendMessage add message, 触发native处理 sendMessage
	function _doSend(message, responseCallback) {
		if (responseCallback) {
			var callbackId = 'cb_' + (uniqueId++) + '_' + new Date().getTime();
			responseCallbacks[callbackId] = responseCallback;
			message.callbackId = callbackId;
		}

		sendMessageQueue.push(message);
		messagingIframe.src = CUSTOM_PROTOCOL_SCHEME + '://' + QUEUE_HAS_MESSAGE;
	}

	// 提供给native调用,该函数作用:获取sendMessageQueue返回给native,由于android不能直接获取返回的内容,所以使用url shouldOverrideUrlLoading 的方式返回内容
	function _fetchQueue() {
		var messageQueueString = JSON.stringify(sendMessageQueue);
		sendMessageQueue = [];
		//android can't read directly the return data, so we can reload iframe src to communicate with java
		messagingIframe.src = CUSTOM_PROTOCOL_SCHEME + '://return/_fetchQueue/' + encodeURIComponent(messageQueueString);
	}

	//提供给native使用,
	function _dispatchMessageFromNative(messageJSON) {
		setTimeout(function() {
			var message = JSON.parse(messageJSON);
			var responseCallback;
			//java call finished, now need to call js callback function
			if (message.responseId) {
				responseCallback = responseCallbacks[message.responseId];
				if (!responseCallback) {
					return;
				}
				responseCallback(message.responseData);
				delete responseCallbacks[message.responseId];
			} else {
				//直接发送
				if (message.callbackId) {
					var callbackResponseId = message.callbackId;
					responseCallback = function(responseData) {
						_doSend({
							responseId: callbackResponseId,
							responseData: responseData
						});
					};
				}

				var handler = WebViewJavascriptBridge._messageHandler;
				if (message.handlerName) {
					handler = messageHandlers[message.handlerName];
				}
				//查找指定handler
				try {
					handler(message.data, responseCallback);
				} catch (exception) {
					if (typeof console != 'undefined') {
						console.log("WebViewJavascriptBridge: WARNING: javascript handler threw.", message, exception);
					}
				}
			}
		});
	}

	//提供给native调用,receiveMessageQueue 在会在页面加载完后赋值为null,所以
	function _handleMessageFromNative(messageJSON) {
		console.log(messageJSON);
		if (receiveMessageQueue && receiveMessageQueue.length > 0) {
			receiveMessageQueue.push(messageJSON);
		} else {
			_dispatchMessageFromNative(messageJSON);
		}
	}

	function setDefaultHandler(messageHandler){
		WebViewJavascriptBridge._messageHandler = messageHandler;
	}

	var WebViewJavascriptBridge = window.WebViewJavascriptBridge = {
		init: init,
		send: send,
		setDefaultHandler: setDefaultHandler,
		registerHandler: registerHandler,
		callHandler: callHandler,
		_fetchQueue: _fetchQueue,
		_handleMessageFromNative: _handleMessageFromNative
	};

	var doc = document;
	_createQueueReadyIframe(doc);
	var readyEvent = doc.createEvent('Events');
	readyEvent.initEvent('WebViewJavascriptBridgeReady');
	readyEvent.bridge = WebViewJavascriptBridge;
	doc.dispatchEvent(readyEvent);

	setTimeout(_callWVJBCallbacks, 0);
	function _callWVJBCallbacks() {
		WebViewJavascriptBridge.init();
		var callbacks = window.WVJBCallbacks;
		delete window.WVJBCallbacks;
		for (var i=0; i<callbacks.length; i++) {
			callbacks[i](WebViewJavascriptBridge);
		}
	}
})();